package ae.pcfc.cldos.online.web.controller.client.company.vv.cancel;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.ws.client.WebServiceIOException;
import org.springframework.ws.soap.client.SoapFaultClientException;

import ae.pcfc.cldos.online.common.ConstantsCommon.Steps;
import ae.pcfc.cldos.online.common.clddb.domain.ServiceMaster;
import ae.pcfc.cldos.online.common.clddb.domain.VisitVisaCancel;
import ae.pcfc.cldos.online.common.delegate.FnpGSDelegate;
import ae.pcfc.cldos.online.common.delegate.VisitVisaCancelDelegate;
import ae.pcfc.cldos.online.common.exception.GSAppException;
import ae.pcfc.cldos.online.common.exception.InvalidEmpIdException;
import ae.pcfc.cldos.online.common.exception.PaymentException;
import ae.pcfc.cldos.online.common.exception.RequestAllreadyExistException;
import ae.pcfc.cldos.online.common.exception.UltimusAppException;
import ae.pcfc.cldos.online.common.vo.AppSaveResponseVO;
import ae.pcfc.cldos.online.common.vo.FileVO;
import ae.pcfc.cldos.online.common.vo.vv.cancel.VisitVisaCancelDetailsVO;
import ae.pcfc.cldos.online.common.vo.vv.cancel.VisitVisaCancelVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPCatalogVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPParameterVO;
import ae.pcfc.cldos.online.web.Constants;
import ae.pcfc.cldos.online.web.PageType;
import ae.pcfc.cldos.online.web.ViewPath;
import ae.pcfc.cldos.online.web.ViewUtils;
import ae.pcfc.cldos.online.web.model.FilesIncomingBean;
import ae.pcfc.cldos.online.web.model.VVCancelModel;
import ae.pcfc.cldos.online.web.services.breadcrumbs.BreadCrumbsFactoryService;
import ae.pcfc.cldos.online.web.services.fnp.FnpParametersCheckService;

/**
 * 
 * @author arosa
 *
 */
@Controller
@RequestMapping(ViewPath.__VV_CANCEL)
public class VVCancelSubmitController extends VVCancelBase {

	private static final String VV_CAN_VIEW_PATH = "client.company.vvcancel.form";
	
	@Autowired
	@Qualifier("visitVisaCancelDelegate")
	private VisitVisaCancelDelegate visitVisaCancelDelegate;
	
	@Autowired
	@Qualifier("FnpGSDelegate")
	private FnpGSDelegate fnpGSDelegate;
	
	@Autowired
	private FnpParametersCheckService fnpParametersCheckService;
	
	@RequestMapping(method=RequestMethod.GET, value="/form.htm")
	public ModelAndView form(@ModelAttribute(value="vvCancelModel") VVCancelModel vvCancelModel, ModelMap model){
		model.put("submitUri", ViewPath.__VV_CANCEL+"/form.htm");
		vvCancelModel.setVvcExitMode(VisitVisaCancel.__EXIT_WITH);
		return new ModelAndView(VV_CAN_VIEW_PATH);
	}
	
	@ModelAttribute
	public void populateBreadCrumbs(ModelMap model, @RequestParam(required=false) String appId) {
		if(appId==null){//if submit new
			breadCrumbsFactoryService.populateVisitVisaTermBreadcrumb(model);
		} else { //for resubmition
			breadCrumbsFactoryService.populateVisitVisaCancelTasktBreadcrumb(model, appId, BreadCrumbsFactoryService.TASK_TYPE_RESUBMIT);
		}
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/resubmitForm.htm")
	public ModelAndView resubmitForm(
			@RequestParam String appId,
			ModelMap model,
			@ModelAttribute(value="vvCancelModel") VVCancelModel vvCancelModel) throws Exception{
		
		populateResubmitInfo(appId, vvCancelModel, model);
		return new ModelAndView(VV_CAN_VIEW_PATH);
	}
	
	private void populateResubmitInfo(String appId, VVCancelModel vvCancelModel, ModelMap model) throws NumberFormatException, Exception{
		VisitVisaCancelVO visitVisaCancelVO = 
				visitVisaCancelDelegate.getEmploymentVisaCancelationAppInfo(
						encryptionDelegate.decodeAndDecrypt(appId), getUserVO(), Steps.RESUBMIT);
		
		List<FileVO> fileVOList = visitVisaCancelVO.getFileVOList();
		model.put("files", fileVOList);
		model.put("exitDocument", visitVisaCancelVO.getExitDocument());
		model.put("isResubmit", true);
		model.put("appId", appId);
		model.put("comments", visitVisaCancelVO.getApplicationCommentVOs());
		model.put("submitUri", ViewPath.__VV_CANCEL+"/resubmitForm.htm?appId="+appId);
		
		if(vvCancelModel!=null){
			mapper.map(visitVisaCancelVO.getVisaCancelDetailsVO(), vvCancelModel);
		}
	}
	
	private void populateResubmitInfo(String appId, ModelMap model) throws NumberFormatException, Exception{
		populateResubmitInfo(appId, null, model);
	}
	
	@ModelAttribute(Constants.__FNP_CATALOG_MODEL_KEY)
	public List<FNPCatalogVO> populateFinanceReviewerInfoModel(HttpServletRequest request) {
		return fnpGSDelegate.getFnpCatalogVOsByServiceCode(ServiceMaster.EV_CANCELATION.toString());
		
	}
	
	@RequestMapping(method=RequestMethod.POST, value={"/form.htm", "/resubmitForm.htm"})
	public ModelAndView submit(
			HttpServletRequest request,
			ModelMap model,
			@RequestParam(required=false, defaultValue="false") boolean isResubmit,
			@RequestParam(required=false) String fnpServiceCode,
			@RequestParam(required=false) String appId,
			@ModelAttribute(value="filesIncomingBean") @Valid FilesIncomingBean filesIncomingBean,
			BindingResult fileErrors,
			@ModelAttribute(value="vvCancelModel") @Valid VVCancelModel vvCancelModel,
			BindingResult errors
			) throws Throwable{
		
		ModelAndView mav = null;
		List<FNPParameterVO> allParams = null;
		if(!vvCancelModel.getVvcExitMode().equals("STATUS_YES")){
			if(securityService.isCompanyAdmin() && (fnpServiceCode==null || fnpServiceCode.isEmpty())){
				errors.reject("no.payment.code");
			} else if(securityService.isCompanyAdmin()){
				allParams = fnpGSDelegate.retreiveFNPParameters(Arrays.asList(new String[]{fnpServiceCode}));
				List<FNPParameterVO> notFeeled = fnpParametersCheckService.feelParamsAndGetNotFeeled(request, allParams);
				if(notFeeled.size()>0){
					errors.reject("sdgsd", "Recomplete payment info please");
				}
			}
		}
		
		if (errors.hasErrors() || fileErrors.hasErrors()) {
			
			System.out.println("there is errors : " );
			for(ObjectError error : errors.getAllErrors())
			{
				System.out.println(error.getCode() + " " + error.getDefaultMessage());
			}

			mav =  new ModelAndView(VV_CAN_VIEW_PATH);;

		}else{
			VisitVisaCancelDetailsVO visitVisaCancelDetailsVO = 
					new VisitVisaCancelDetailsVO();
			mapper.map(vvCancelModel, visitVisaCancelDetailsVO);
			
			VisitVisaCancelVO visitVisaCancelVO = 
					new VisitVisaCancelVO();
			visitVisaCancelVO.setFileVOList(getFileVOList(filesIncomingBean));
			visitVisaCancelVO.setUserVO(getUserVO());
			visitVisaCancelVO.setFnpServiceCode(fnpServiceCode);
			visitVisaCancelVO.setFnpParams(allParams);
			visitVisaCancelVO.setVisaCancelDetailsVO(visitVisaCancelDetailsVO);
			visitVisaCancelVO.setComment(vvCancelModel.getAdminComments());
			
			AppSaveResponseVO appSaveResponseVO = null;
			try{
				if(isResubmit){
					appSaveResponseVO = visitVisaCancelDelegate.reSubmit(visitVisaCancelVO, encryptionDelegate.decodeAndDecrypt(appId));
				}else {
					appSaveResponseVO = visitVisaCancelDelegate.submit(visitVisaCancelVO);
				}
			} catch (PaymentException e) {
				errors.reject("error.payment");
			}catch (RequestAllreadyExistException e) {
				errors.reject("request.vvc.exist");
			}catch(InvalidEmpIdException e){
				errors.reject("invalid.employee");
			}catch(GSAppException e){
				errors.reject("unable.to.proceed.gs.down");
			}catch(UltimusAppException e){
				errors.reject("unable.to.proceed.ultimus.down");
			}catch(WebServiceIOException e){
				e.printStackTrace();
				errors.reject("unable.to.proceed.gs.fnp.down");
			}catch(SoapFaultClientException e){
				e.printStackTrace();
				errors.reject("unable.to.proceed.gs.fnp.down");
			}catch(Exception e){
				e.printStackTrace();
				errors.reject("unable.to.proceed");
			}
			
			if(errors.hasErrors()){
				mav =  new ModelAndView(VV_CAN_VIEW_PATH);
			}else{
				Map<String, String> paramMap = new HashMap<String, String>();
				paramMap.put(Constants.__REFRENCE_NO, appSaveResponseVO.getReferenceNo());
				if(appSaveResponseVO.getIncidentNo() !=null){
					paramMap.put(Constants.__INCIDENT_NO, appSaveResponseVO.getIncidentNo());
				}
				mav = new ModelAndView(ViewUtils.getRedirect(ViewPath.__CONFIRMATION, PageType.SHOW, paramMap));
			}
		}
		
		if((errors.hasErrors() || fileErrors.hasErrors()) ){
			if(isResubmit){
				populateResubmitInfo(appId, model);
			} else{
				model.put("submitUri", ViewPath.__VV_CANCEL+"/form.htm");
			}
		}
		
		return mav;
	}
}
